package org.beetl.json;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.beetl.json.action.ClassCycleIncludeAction;
import org.beetl.json.action.ClassExcludeAction;
import org.beetl.json.action.ClassIncludeAction;
import org.beetl.json.action.ClassOrderAction;
import org.beetl.json.action.FormatAction;
import org.beetl.json.action.IValueAction;
import org.beetl.json.action.IfAction;
import org.beetl.json.action.KeyChangeAction;
import org.beetl.json.action.KeyIgnoreAction;
import org.beetl.json.action.UserDefFormatAction;
import org.beetl.json.action.ValueChangeAction;
import org.beetl.json.loc.AttributeLocation;
import org.beetl.json.loc.ClassLocation;
import org.beetl.json.loc.ClassTypeLocation;
import org.beetl.json.loc.TypeLocation;

/** 序列化规则解析
 * @author xiandafu
 *
 */
public class PolicyParser {
	
	public List<Location> init(Class cls){
	
		Json json = (Json)cls.getAnnotation(Json.class);
		
		if(json!=null){
			JsonPolicy[] policys = json.policys();
			List<Location> list = new ArrayList<Location>(policys.length);
			for(JsonPolicy po:policys){	
				list.add(parse(cls,po.location(),po.action()));
			}	
		    Class parent = cls.getSuperclass();
		    if(!JsonTool.isStopParse(parent.getName())){
		    	List  supers = init(parent);
				list.addAll(supers);
				return list;		    
		    }
			return list;
			
		}else{
			return new ArrayList();
		}
		
	}
	
	protected static Location  parse(Class c,String loc,String act){
		
		LocationAction action = null;
		Location location = null;
		//先处理位置=====
		if(loc.startsWith("~")){
			//某个指令
			String cmd = loc.substring(1);
			if(cmd.equals("f")){
				//浮点
				location = new TypeLocation(cmd);
				
			}else if(cmd.equals("d")){
				location = new TypeLocation(cmd);
			}else if(cmd.equals("*")){
				if(c==null){
					throw new JsonException(JsonException.ERROR,"错误使用'*'来指定Location,必须具体类里");
				}
				location = new ClassLocation(c);
			}else if(cmd.equals("c")){
				location = new TypeLocation(cmd);
			}else if(cmd.startsWith("L/")){
				//某个类
				String clsName = cmd.substring(2,cmd.length()-1);
				if(clsName.endsWith("*")){
					location = new ClassTypeLocation(getClassByName(clsName.substring(0,clsName.length()-1)),true);
					
				}else{
					location = new ClassTypeLocation(getClassByName(clsName),true);
				}
				
			}
			else{
				throw new UnsupportedOperationException();
			}
		}else{
			//暂时忽略user.wife:i这种到下一级的属性
			String attrName = loc;
			location = new AttributeLocation (attrName);
			
		}
	
		action = parseAction(act);
		
		location.setAction(action);	
		return location;
	}
	
	protected static List<Location>  parse(Class c,String policy){
		//根据逗号解析会有问题
		String[] strs = policy.split(",");
		 List<Location>  list = new ArrayList<Location> ();
		for(String str:strs){
			String[] temp = str.split(":");
			String loc=temp[0], act=temp[1];
			list.add(parse(c,loc,act));
			
			
		}
		
		return list;
		
		
	}
	
	protected static LocationAction parseAction(String act){
		LocationAction action = null;
		//处理action=====		
		if(act.startsWith("i")){
			//忽略操作
			action = new KeyIgnoreAction();
			
		}else if(act.startsWith("f")){
			//格式化操作 f'yyyy-MM-dd'
			if(act.charAt(1)=='/'){
				String format = act.substring(2,act.length()-1);
				action = new FormatAction(format);
			}else{
				String format = act.substring(2);
				action = new UserDefFormatAction(format);
			
			}
			
		}else if(act.startsWith("nn")){
			//修改keyName
			String targetName = act.substring(3,act.length()-1);
			action = new KeyChangeAction(targetName);
			
		}else if(act.startsWith("U")){
			String names = act.substring(2,act.length()-1);
			action = new ClassIncludeAction(names);
		}else if(act.startsWith("I")){
			String names = act.substring(2,act.length()-1);
			action = new ClassExcludeAction(names);
		}
		else if(act.startsWith("?")){
			int index = act.indexOf("->");
			String condtion = act.substring(1,index);
			String output = act.substring(index+2,act.length());
			action = new IfAction(condtion,output);
		}else if(act.startsWith("$.")){
			int index = act.indexOf("->");
			
			if(index!=-1){
				String methodName = act.substring(2,index);
				String chainActionString = act.substring(index+2);
				IValueAction chainAction = (IValueAction)parseAction(chainActionString);
				ValueChangeAction va = new ValueChangeAction(methodName,chainAction);
				return va;
				
			}else{
				String methodName = act.substring(2);
				ValueChangeAction va = new ValueChangeAction(methodName);
				return va;
				
			}
		}else if(act.startsWith("O")){
			//排序
			String names = act.substring(2,act.length()-1);
			action = new ClassOrderAction(names);
		}else if(act.startsWith("Ci")){
			//循环中包括
			String names = act.substring(3,act.length()-1);
			action = new ClassCycleIncludeAction(names);
		}
		
		return action;
	}
	protected static Class getClassByName(String name){
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException e) {
			throw new JsonException(JsonException.ERROR, "找不到类"+name);
		}
	}
	
}
